package com.hjs.tools;

import com.hjs.bean.*;
import com.hjs.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;

import java.time.LocalDate;
import java.util.List;

/**
 * @author violetfreesia
 * @date 2020/06/19
 */

@Slf4j
public class EvaluationUtil {
    public static boolean evaluationResult(RequestUtil requestUtil, SqlSession sqlSession,int type) {
        Double IRI, RQI, PCI, PQI, indiviualScore;
        IRI = 0.0;
        indiviualScore = 0.0;
        Integer RQIGrade,PCIGrade,PQIGrade;
        RegularInspectionMapper regularInspectionMapper = sqlSession.getMapper(RegularInspectionMapper.class);
        RoadTypeMapper roadTypeMapper = sqlSession.getMapper(RoadTypeMapper.class);
        EvaluationResultsMapper evaluationResultsMapper = sqlSession.getMapper(EvaluationResultsMapper.class);
        RegularInspection regularInspection = regularInspectionMapper.getOneRegularInspectionById(requestUtil.getInt("regularInspectionID"));
        ViewMapper viewMapper = sqlSession.getMapper(ViewMapper.class);
        /*
         * type=1最后添加的为平整度
         * type=2最后添加的为损害情况
         */
        if(type == 1) {
            IRI = requestUtil.getDouble("IRI");
            Integer pavementDamageComID = regularInspection.getPavementDamageComID();
            List<PavementDamageView> damageViews = viewMapper.getPavementDamageViewById(pavementDamageComID);
            indiviualScore = damageViews.get(0).getIndividualScore();
        } else if(type == 2) {
            PavementFlatness pavementFaltness = regularInspectionMapper.getPavementFaltnessById(regularInspection.getFlatnessID());
            IRI = pavementFaltness.getIRI();
            Double damageArea = getDamageArea(requestUtil.getInt("damageTypeID0"),requestUtil.getDouble("damageLength0"),requestUtil.getDouble("damageWidth0"));
            Double damageDensity = getDamageDensity(damageArea,requestUtil.getDouble("totalLength"),requestUtil.getDouble("totalWidth"));
            indiviualScore = getScoreByDamageDensity(requestUtil.getInt("damageTypeID0"),damageDensity);
        }
        RQI = TechnicalConditionEvaluation.calculateRQI(IRI);
        PCI = TechnicalConditionEvaluation.calculatePCI(indiviualScore);
        RoadType roadType = roadTypeMapper.getRoadTypeByRoadWayId(regularInspection.getRoadwayID());
        PQI = TechnicalConditionEvaluation.calculatePQI(RQI,PCI,roadType.getRoadTypeID());
        RQIGrade = TechnicalConditionEvaluation.getRQIGradeIdByRQI(RQI,roadType);
        PCIGrade = TechnicalConditionEvaluation.getPCIGradeIdByPCI(PCI,roadType);
        PQIGrade = TechnicalConditionEvaluation.getPQIGradeIdByPQI(PQI,roadType);
        LocalDate localDate = LocalDate.now();
        EvaluationResults evaluationResults = new EvaluationResults(null,requestUtil.getInt("regularInspectionID"),localDate,
                PQI,PQIGrade,RQI,IRI,RQIGrade,PCI,PCIGrade);
        return evaluationResultsMapper.addOne(evaluationResults);
    }

    private static Double getScoreByDamageDensity(Integer damageTypeId,Double damageDensity) {
        Double density = null;
        try (SqlSession sqlSession = Mapper.getSqlSession()) {
            StandardMapper standardMapper = sqlSession.getMapper(StandardMapper.class);
            List<DamageStandard> allDamageStandard = standardMapper.getAllOnePointMinusByDamageTypeId(damageTypeId);
            /*
             * 遍历allDamageStandard列表
             * 若损坏标准匹配
             * 且当前密度夹在某两个中间，则找到所需单项扣分循环结束
             * 注：损坏密度夹在两个扣分标准之间时，取小的那个密度对应的扣分标准扣分
             */
            if (damageDensity < 0.01) {
                density = 0.0;
            } else if (damageDensity == 100) {
                density = allDamageStandard.get(5).getPointMinus();
            } else {
                for (int i = 0; i < allDamageStandard.size() - 1; i++) {
                    DamageStandard downDamageStandard = allDamageStandard.get(i);
                    DamageStandard upDamageStandard = allDamageStandard.get(i + 1);
                    if (damageDensity >= downDamageStandard.getDamageDensity()
                            && damageDensity < upDamageStandard.getDamageDensity()) {
                        density =  downDamageStandard.getPointMinus();
                        break;
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.toString());
        }
        return density;
    }

    private static Double getDamageArea(Integer damageTypeId, Double damageLength, Double damageWidth) {
        return asphalt.all(damageTypeId,damageLength,damageWidth);
    }

    private static Double getDamageDensity(Double damageArea,Double totalLength, Double totalWidth) {
        return damageArea/(totalLength * totalWidth);
    }
}
